import * as L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import '@geoman-io/leaflet-geoman-free'
import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css'
import 'leaflet.polyline.snakeanim'
import { getToken } from '../auth'
const windowInstance: any = window
const token: string = getToken()
const mapOptions: IMapOptions = {
	zoomControl: true, //禁用 + - 按钮
	doubleClickZoom: false, // 禁用双击放大
	attributionControl: false, // 显示右下角leaflet标识
	minZoom: -3,
	maxZoom: 5,
	center: [ 0, 0 ],
	zoom: 0,
	crs: L.CRS.Simple,
	zoomSnap: 0.1,
	zoomDelta: 0.3,
}
class Map implements IMap {
	leafletMap = null
	tags = {}
	mapObj = {} as IMapobj
	polygon = null
	selectedId = ''
	nowIndex = 0
	playIndex = 1
	filterCode = ''
	markerList = []
	polygonList = {}
	nowPlayPolygonList = []
	devicesCallback = null
	isActive = false
	isPlay = true
	featureGroup = null
	constructor(el: string, options?: Record<string, any>) {
		this.init(el, options)
	}
	/**
	 * @param 初始化leaflet
	 * @returns leafletMap
 */
	init(el: string, options?: Record<string, any>): any {
		if (!el) return
		const _this = this
		this.leafletMap = L.map(el, {
			...mapOptions,
			...options,
		})
		this.leafletMap.on('movestart', () => (_this.isActive = true))
		this.leafletMap.on('moveend', () => (_this.isActive = false))
		this.leafletMap.on('zoomstart', () => (_this.isActive = true))
		this.leafletMap.on('zoomend', () => (_this.isActive = false))
		return this.leafletMap
	}
	/**
 * @param 加载地图
 * @returns void
 */
	loadMap(obj: IMapobj) {
		const _this = this
		return new Promise((resolve, reject) => {
			_this.mapObj = obj 

			var imgUrl = _this.mapObj.imageFullUrl

			// 切换地图的时候把之前的标签数组清空
			_this.tags = {}

			var imageObj = new Image()
			imageObj.src = imgUrl
			imageObj.onload = function() {
				//删除图层所有控件
				_this.leafletMap.eachLayer(function(layer) {
					_this.leafletMap.removeLayer(layer)
				})
				let w = imageObj.width,
					h = imageObj.height

				let bounds = [ [ 0, 0 ], [ h, w ] ]

				let imageOverlay = L.imageOverlay(imgUrl, bounds).addTo(_this.leafletMap)

				imageOverlay.on('load', function() {
					_this.leafletMap.fitBounds(bounds)
				})

				// _this.featureGroup = L.featureGroup().addTo(_this.leafletMap);

				// _this.leafletMap.setView([h / 2, w / 2], 0)
				_this.mapObj.width = imageObj.width
				_this.mapObj.height = imageObj.height
				resolve(_this.mapObj)
			}
			imageObj.onerror = (e) => {
				reject(e)
			}
		})
	}
	/**
	 * @param 定位方法
	 * @returns void
	 */
	position(data) {
		const _this = this
		const windowInstance: any = window
		if (_this.isActive) {
			return
		}

		for (let i = 0; i < data.length; i++) {
			let obj = data[i]
			if (_this.mapObj.code != obj.mapCode) {
				continue
			}
			// 先去marker列表里看看能不能找到相同的，如果找到相同的就更新位置 否则就新增
			let r = _this.tags[obj.deviceCode]
			if (r) {
				// 找到了 就更新位置
				_this.tags[obj.deviceCode].leafletTag.setLatLng([ obj.posY, obj.posX ])
			} else {
				// 没找到 创建
				let myIcon = L.icon({
					iconUrl: windowInstance.config.base_url + obj.userTypeIconUrl,
					iconSize: [ 30, 30 ],
					iconAnchor: [ 15, 15 ],
					className: `marker_icon ` + obj.deviceCode,
				})
				let leafletTag = L.circleMarker([ obj.posY, obj.posX ], {
					className: obj.memberName,
					radius: 10,
					fillColor: 'red',
					fillOpacity: 1,
					weight: 1,
					icon: myIcon,
				}).addTo(_this.leafletMap)
				let toolTipContent =  `${obj?.memberName || '-'}`;
				let t = document.createElement("div");
				t.innerHTML = toolTipContent;
				leafletTag.setTooltipContent(t)
			leafletTag.bindTooltip(t, { permanent: true, offset: L.point(0, -10), direction: "top", className: "tag_info_tooltip" }).openTooltip();

				obj.leafletTag = leafletTag

				_this.tags[obj.deviceCode] = obj

				_this.reflushDevices()
			}
			_this.filterItem(obj)
		}
	}
	/**
	 *
	 * @param points 历史轨迹点
	 * @returns voids
	 * @description 绘画历史轨迹
	 */
	setHistoryLine(data) {
		if (!data.length) return

		const _this = this
		let nowPlayIndex = 0
		let polyline = null
		// 根据地图id分割成二维数组
		const splitArraysByMapId = (datas) => {
			const resultArrays = []
			let currentArray = []
			for (let i = 0 , length=datas.length; i < length; i++) {
				if (i === 0 || datas[i].mapFid !== datas[i - 1].mapFid) {
					if (currentArray.length > 0) {
						resultArrays.push(currentArray)
					}
					currentArray = []
				}
				currentArray.push(datas[i])
			}

			if (currentArray.length > 0) {
				resultArrays.push(currentArray)
			}

			return resultArrays
		}

		const resultArrays = splitArraysByMapId(data)
		// 加载下一张地图的轨迹
		let loadNextMap = () => {
			if (nowPlayIndex < resultArrays.length - 1) {
					nowPlayIndex++
					showMarkerLine(resultArrays[nowPlayIndex])
				}
		}
		// 播放轨迹
		let showMarkerLine = async (datas:ITag[]) => {
			let firstObj = datas[0]
			await this.loadMapFunc(firstObj)
			const points = datas.map((item:ITag) => {
				return [ item.posY || 0, item.posX || 0 ]
			})

				if (points.length == 1) {
					try {
						L.circleMarker(points[0], {
							radius: 5,
							fillColor: 'red',
							fillOpacity: 1,
							weight: 1,
						}).addTo(_this.leafletMap)
						setTimeout(() => {
							loadNextMap()
						}, 2000)
					} catch {
						loadNextMap()
					}
					return
				}

			polyline = L.polyline(points, { color: 'red' ,opacity:.6}).addTo(_this.leafletMap)

			polyline.on('snakeend', (e) => {
				loadNextMap()
			})
			try {
				polyline.snakeIn()
			} catch {
				loadNextMap()
			}
		}

		// 默认执行一次
		showMarkerLine(resultArrays[nowPlayIndex])
	}
	/**
	 *
	 * @param points 区域轨迹点
	 * @returns voids
	 * @description 加载区域
	 */
	loadArea(points: []) {
		const _this = this
		let height = this.mapObj.height || 768
		setTimeout(() => {
			var bounds = points.map((item) => {
				return [ height + item[0], item[1] ]
			})
			let polygon = L.polygon(bounds, { color: 'red', zIndex: 999 }).addTo(_this.leafletMap)
		}, 500)
	}
	/**
	* @param 设置选中标签
		* @returns void
 */
	setselectedId(id) {
		this.selectedId = id
	}
	/**
		* @param 设置刷新标签
		* @returns void
	*/
	reflushDevices() {}
	/**
		* @param 过滤标签
		* @returns void
	*/
	filterItem(obj: ITag) {}
	/**
		* @param 加载地图
		* @returns void
	*/
	async loadMapFunc(obj) {
		await this.loadMap({
			imageFullUrl: `${windowInstance.config.base_url}/Maps/pic/${obj.mapId}?access_token=${token}`,
			width: 50,
			height: 50,
			code: obj.mapCode,
		})
	}
}

export default Map
